//
//  SystemCDefinitions.cpp
//  sad
//
//  Created by Christopher Kemsley on 2/5/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#include <iostream>
#include "Types.hpp"
#include "XMLParser.hpp"
#include "ModuleFactory.hpp"
#include "Exception.hpp"
#include <sstream>

using namespace Sim ;





/**** URL XML Decoder ****/

struct	IntervalParser : public XMLParsingAgent
{
	IntervalParser ()
	:	XMLParsingAgent ("interval") { }
	
	
	virtual XMLParser::Offset	parse	( std::string const & file , Any & interval , XMLParser::Offset iStart )
		{
		std::string			stringValue ;
		XMLParser::Offset	length	=	XMLParserHelper :: getImmediateString ( file , iStart , stringValue ) ;
		
		
		if ( length )
			{
			std::stringstream	str		( stringValue ) ;
			
			unsigned long		value	=	0 ;
			std::string			unit ;
			
			str >> value ;
			str >> unit ;
			
			if ( unit.find("ps") != std::string::npos )
				interval = Interval ( 0 , 0 , value ) ;
			
			else if ( unit.find("us") != std::string::npos )
				interval = Interval ( 0 , value , 0 ) ;
			
			else
				interval = Interval ( value , 0 , 0 ) ;
			}
		
		
		return iStart + length + /*"</interval>"*/11 ;
		}
} ;
IntervalParser _IntervalParser ;











/**** URL XML Decoder ****/

struct	VariantParser : public XMLParsingAgent
{
	VariantParser ()
	:	XMLParsingAgent ("variant") { }
	
	
	virtual XMLParser::Offset	parse	( std::string const & file , Any & value , XMLParser::Offset iStart )
		{
		static std::string const	_endTag	( "</variant>" ) ;
		XMLParser::Offset	end			=	file . find ( _endTag , iStart ) ;
		XMLParser::Offset	newOffset	=	end + _endTag.size() ;
		
		static std::string const	_configName		( "<configURL>" ) ;
		static std::string const	_instanceName	( "<instanceName>" ) ;
		static std::string const	_builderName	( "<builderName>" ) ;
		
		XMLParser::Offset	pConfigName			=	file . find ( _configName , iStart ) ;
		XMLParser::Offset	pInstanceName		=	file . find ( _instanceName , iStart ) ;
		XMLParser::Offset	pBuilderName		=	file . find ( _builderName , iStart ) ;
		
		if ( pConfigName>end || pInstanceName>end || pBuilderName>end )
			ThrowException ( "XMLParsingAgent::VariantParser" , "Failed to find the necessary arguments for the <variant> tag. {"<<pConfigName<<","<<pInstanceName<<","<<pBuilderName<<"}>"<<end<<"" , __FILE__,__LINE__ ) ;
		
		
		
		value	=	ModelVariant() ;
		ModelVariant & variant	=	value.as<ModelVariant>() ;
		
		
		std::string sConfigName ;
		XMLParserHelper :: getImmediateString ( file , pConfigName+_configName.size() , sConfigName ) ;
		
		
		variant.configURL = sConfigName ;
		XMLParserHelper :: getImmediateString ( file , pInstanceName+_instanceName.size() , variant.instanceName ) ;
		XMLParserHelper :: getImmediateString ( file , pBuilderName+_builderName.size() , variant.builderName ) ;
		
		
		return newOffset ;
		}
} ;
VariantParser _VariantParser ;












struct	LocationParser : public XMLParsingAgent
{
	LocationParser ()
	:	XMLParsingAgent ("location") { }
	
	
	virtual XMLParser::Offset	parse	( std::string const & file , Any & value , XMLParser::Offset iStart )
	{
	static std::string const	_endTag	( "</location>" ) ;
	XMLParser::Offset	end			=	file . find ( _endTag , iStart ) ;
	XMLParser::Offset	newOffset	=	end + _endTag.size() ;
	
	std::string stringValue ;
	XMLParser::Offset	length		=	XMLParserHelper :: getImmediateString ( file , iStart , stringValue ) ;
	
	if ( length < 3 )
		ThrowException ( "XMLParsingAgent::LocationParser" , "String isn't long enough to be a location: "<<stringValue , __FILE__,__LINE__ ) ;
	
	
	value	=	Location( -999999. , -999999 ) ;
	Location & location	=	value.as<Location>() ;
	
	char const	*	str	=	stringValue.c_str() ;
	
	sscanf ( str , "%lf%*[^1234567890.-]%lf" , &location.x , &location.y ) ;
	
	if ( location.x==-999999. || location.y==-999999. )
		ThrowException ( "XMLParsingAgent::LocationParser" , "Didn't find x and y in: "<<stringValue<<" (got "<<location<<")" , __FILE__,__LINE__ ) ;
		
	
	
	return newOffset ;
	}
} ;
LocationParser _LocationParser ;
